#include "sls-table.h"
#include "ns3/log.h"

namespace ns3{

	MapEntry::MapEntry(Vector position, Time time, bool researchFlag , uint8_t numSeq):
	m_position(position)
	{}

	void PositionTable::AddEntry(Ipv4Address id, Vector position, Time time, bool flag, uint8_t seq ){

		NS_LOG_UNCOND("ENTROU NO ADD ENTRY");

		std::map<Ipv4Address, MapEntry >::iterator i = m_table.find(id);
		if(i != m_table.end () || id.IsEqual(i->first))
		{
			/*FIXME: lifetime??*/
			m_table.erase(id);
			m_table.insert(std::make_pair(id, MapEntry(position, Simulator::Now(), false, seq)));

			return;
		}

		m_table.insert(std::make_pair(id, MapEntry(position, Simulator::Now(), false, seq)));
		NS_LOG_UNCOND("ADDED ENTRY: " << id << " " << position.x << "," << position.y);

		PrintEntry();
	}

	//Ideia do PrintEntry é imprimir tabela sempre que é feito um AddEntry

	void PositionTable::PrintEntry(){

		NS_LOG_UNCOND("PRINT ENTRY");

		for (std::map<Ipv4Address, MapEntry >::iterator iter = m_table.begin();
			      iter != m_table.end(); ++iter )
			NS_LOG_UNCOND(iter->first);
		return;
	}


	Vector PositionTable::GetPosition(Ipv4Address id){
		std::map<Ipv4Address, MapEntry >::iterator i = m_table.find(id);
		if(i == m_table.end () && !id.IsEqual(i->first))
		{
			//return Vector(0,0);
		}
		return i->second.GetPosition();
	}

	//Assuming that the location service will only set a new location if is more updated
	void PositionTable::SetPosition(Ipv4Address id, Vector position){
		std::map<Ipv4Address, MapEntry >::iterator i = m_table.find(id);
		if(i == m_table.end () && !id.IsEqual(i->first))
		{
			AddEntry(id, position, Time(0), false, 0);
		}
		return i->second.SetPosition(position);
	}

	void PositionTable::SetSpeed(Ipv4Address id,int speed){
		std::map<Ipv4Address, MapEntry >::iterator i = m_table.find(id);
		if(i == m_table.end () && !id.IsEqual(i->first))
		{
			return;
		}
		i->second.SetSpeed(speed);
	}

	MapEntry PositionTable::GetEntry(Ipv4Address id){
		//std::map<Ipv4Address, MapEntry >::iterator i = m_table.find(id);
		return m_table.find(id)->second;

	}


	void PositionTable::DeleteEntry(Ipv4Address id){
		m_table.erase(id);
	}


	void PositionTable::Purge(){
	/*		std::map<Ipv4Address, MapEntry >::iterator i;
		for(i = m_table.begin(); !(i == m_table.end()); i++)
		{
			if(m_entryLifeTime + GetEntryUpdateTime(i->first) <= Simulator::Now())
			{
				m_table.erase(i->first);
			}	
		}
		 last element is not used in for cicle
		if(m_entryLifeTime + GetEntryUpdateTime(i->first) <= Simulator::Now())
		{
			m_table.erase(i->first);
		}*/
	}

	Time PositionTable::GetEntryUpdateTime(Ipv4Address id){
			std::map<Ipv4Address, MapEntry >::iterator i = m_table.find(id);
			if(i == m_table.end () && !id.IsEqual(i->first))
			{
				return Time(0);
			}
			return i->second.GetTime();
		}


	void PositionTable::Clear(){
		m_table.clear ();
	}

}
